#include "EstadoDeDecisionDeResultado.h"
#include "MovimientoDeEjercitosInvalidoException.h"
#include "MensajeMostrarDados.h"
#include "MensajeDeFinalizacion.h"
#include <list>
#include <iostream>
#include "Dado.h"
#include "CartaDeObjetivos.h"
using namespace std;

EstadoDeDecisionDeResultado::EstadoDeDecisionDeResultado(EstadoDeAtaque* estadoDeAtaque)
{
	this->estadoDeAtaque = estadoDeAtaque;
}

void EstadoDeDecisionDeResultado::decidirResultado() {
	Ataque* unAtaque = this->estadoDeAtaque->getAtaque();
	list<Dado*>* dadosDeAtacante = this->estadoDeAtaque->getDadosTiradosPorAtacante();
	list<Dado*>* dadosDeDefensor = this->estadoDeAtaque->getDadosTiradosPorDefensor();
	
	//ORDENO LOS DADOS
	for(list<Dado*>::iterator it = dadosDeAtacante->begin(); it != dadosDeAtacante->end(); it++)
		for(list<Dado*>::iterator ite = dadosDeAtacante->begin(); ite != dadosDeAtacante->end(); ite++) {
			list<Dado*>::iterator iteAux = ite;
			iteAux++;
			if (iteAux != dadosDeAtacante->end())
				if ((*ite)->getValor() < (*iteAux)->getValor()) {
					Dado* aux = *ite;
					dadosDeAtacante->erase(ite);
					dadosDeAtacante->push_back(aux);
				}
		}
	for(list<Dado*>::iterator it = dadosDeDefensor->begin(); it != dadosDeDefensor->end(); it++)
		for(list<Dado*>::iterator ite = dadosDeDefensor->begin(); ite != dadosDeDefensor->end(); ite++) {
			list<Dado*>::iterator iteAux = ite;
			iteAux++;
			if (iteAux != dadosDeDefensor->end())
				if ((*ite)->getValor() < (*iteAux)->getValor()) {
					Dado* aux = *ite;
					dadosDeDefensor->erase(ite);
					dadosDeDefensor->push_back(aux);
				}
		}

	MensajeMostrarDados mensaje(*dadosDeAtacante,*dadosDeDefensor,
			unAtaque->getTerritorioAtacante(),unAtaque->getTerritorioEnemigo());
	this->estadoDeAtaque->getEstadoDeRealizacionDePartida()->getJuego()->getServer()->broadcast(mensaje);
	list<Dado*>::iterator it = dadosDeDefensor->begin();
	bool termino = true;
	if ((dadosDeDefensor->size()) == 1)
		termino = false;
	while ((it != dadosDeDefensor->end()) || (!termino)) {
	    Dado* dadoAtacante = dadosDeAtacante->front();
	    dadosDeAtacante->pop_front();
		int defensor = (*it)->getValor();
	    int atacante = dadoAtacante->getValor();
		if (defensor < atacante)
	    	unAtaque->getTerritorioEnemigo()->quitarEjercitos(1);
	    else
	    	unAtaque->getTerritorioAtacante()->quitarEjercitos(1);
		it++;
		if (it == dadosDeDefensor->end())
			termino = true;
	}
	string jugadorEnemigo = unAtaque->getTerritorioEnemigo()->getEnPoderDe();
	JuegoServerImp* juego = this->estadoDeAtaque->getEstadoDeRealizacionDePartida()->getJuego();
	if (unAtaque->getTerritorioEnemigo()->getCantidadDeEjercitos() == 0) {
		unAtaque->getTerritorioAtacante()->quitarEjercitos(unAtaque->getCantidadDeDadosParaAtacar());
		unAtaque->getTerritorioEnemigo()->colocarEjercitos(unAtaque->getCantidadDeDadosParaAtacar(),unAtaque->getJugadorAtacante()->getColor());
	}
	if (this->hayUnGanadorDelJuego()) {
		juego->finalizar();
	}
	else
		this->estadoDeAtaque->setEstado(this->estadoDeAtaque->getEstadoDeDeclaracion());
}

void EstadoDeDecisionDeResultado::moverEjercitos(Jugador* jugador, Territorio* origen, Territorio* destino, unsigned int cantidadDeEjercitos) {
	if ((cantidadDeEjercitos >= this->estadoDeAtaque->getAtaque()->getCantidadDeDadosParaAtacar()) &&
			(origen->getCantidadDeEjercitos() - cantidadDeEjercitos > 0)) {
		origen->quitarEjercitos(cantidadDeEjercitos);			
		destino->colocarEjercitos(cantidadDeEjercitos,jugador->getColor());
		this->estadoDeAtaque->setEstado(this->estadoDeAtaque->getEstadoDeDeclaracion());
	}
	else
		throw MovimientoDeEjercitosInvalidoException();
}

bool EstadoDeDecisionDeResultado::hayUnGanadorDelJuego() {
	JuegoServerImp* juego = this->estadoDeAtaque->getEstadoDeRealizacionDePartida()->getJuego();
	Jugador* jugador = this->estadoDeAtaque->getAtaque()->getJugadorAtacante();
	bool resultado = false;
	CartaDeObjetivos* carta = jugador->getCartaDeObjetivos();
	if ((carta != NULL) && (carta->seCumplio(juego))) {
			MensajeDeFinalizacion mensajeGanador("Eres el ganador del juego por haber cumplido con la mision de "+jugador->getCartaDeObjetivos()->getObjetivo());
			MensajeDeFinalizacion mensajePerdedor(jugador->getNombre()+" ha cumplido con la mision de "+jugador->getCartaDeObjetivos()->getObjetivo());
			juego->getServer()->enviarMensaje(jugador,mensajeGanador);
			for (int i = 0; i < juego->getJugadores()->size(); i++)
				if (juego->getJugadores()->at(i)->getNombre() != jugador->getNombre())
					juego->getServer()->enviarMensaje(juego->getJugadores()->at(i), mensajePerdedor);
			resultado = true;
	}		
	else if (juego->getMapa()->getTerritoriosEnPoderDeJugador(jugador->getColor()) == juego->getMapa()->getCantidadDeTerritorios()) {
			MensajeDeFinalizacion mensajeGanador("Eres el ganador del juego por haber conquistado todos los territorios");
			MensajeDeFinalizacion mensajePerdedor(jugador->getNombre()+" ha conquistado todos los territorios");
			juego->getServer()->enviarMensaje(jugador,mensajeGanador);
			for (int i = 0; i < juego->getJugadores()->size(); i++)
				if (juego->getJugadores()->at(i)->getNombre() != jugador->getNombre())
					juego->getServer()->enviarMensaje(juego->getJugadores()->at(i), mensajePerdedor);
			resultado = true;
	}
	return resultado;
}

EstadoDeDecisionDeResultado::~EstadoDeDecisionDeResultado()
{
}
